﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Miao
{
    public class FSM
    {
        //状态机接口和状态机互相包含，每一个FSM里面包含
        //之前State
        //进行中State
        //下一个State
        public IState PreviousState { get; protected set; }
        public IState CurrentState { get; protected set; }
        public IState NextState { get; protected set; }

        //readonly关键词是只读自段
        protected readonly Dictionary<string, IState> States = new Dictionary<string, IState>();


        //一个泛型抽象添加状态
        public TState AddState<TState>() where TState : IState, new()
        {
            string stateName = typeof(TState).Name;//获取新状态名字
            var state = new TState();
            state.Init(this);
            if (States.Count == 0)
            {
                PreviousState = CurrentState;
                CurrentState = state;
                NextState = state;
            }

            States[stateName] = state;//将新状态填入状态机池中

            return state;
        }
        public TState RemoveState<TState>() where TState : class, IState
        {
            var name = typeof(TState).Name;
            IState state;
            if (States.TryGetValue(name, out state))
            {
                States.Remove(name);
                return state as TState;
            }
            else
            {
                return null;
            }
        }

        public void ChangeState<T>()
        {
            string stateName = typeof(T).Name;
            ChangeState(stateName);
        }
        /// <summary>
        /// 更改状态，但只在不相同时
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void ChangeStateNotSame<T>()
        {
            string stateName = typeof(T).Name;
            if (stateName != CurrentState.Name)
            {
                ChangeState(stateName);
            }
        }
        public IState AddState(IState state, string stateName)//添加实例化类
        {
            state.Init(this);
            if (States.Count == 0)
            {
                PreviousState = CurrentState;
                CurrentState = state;
                NextState = state;
            }
            States[stateName] = state;//将新状态填入状态机池中

            return state;


        }

        public void ChangeState(string stateName)
        {
            if (States.TryGetValue(stateName, out _))
            {
                var nextState = States[stateName];
                ChangeState(nextState);
            }
            else
            {
                UnityEngine.Debug.LogError($"there is no {stateName} State, or you forget to add {stateName} State to FSM");
            }
        }
        public void ChangeState(IState nextState)
        {
            NextState = nextState;
        }

        protected virtual void UpdateStateChange()
        {
            if (NextState != null && CurrentState != null)
            {
                CurrentState.OnExitState();
                PreviousState = CurrentState;
                CurrentState = NextState;
                NextState = null;
                CurrentState.OnStayState();
            }
        }
        /// <summary>
        /// 更新状态机，记得填Time.DeltaTime
        /// </summary>
        /// <param name="deltaTime"></param>
        public virtual void Update(float deltaTime)
        {
            CurrentState?.Reason();
            UpdateStateChange();
            CurrentState?.OnUpdateState(deltaTime);
        }
        /// <summary>
        /// 定时Update
        /// </summary>
        /// <param name="fixedDeltaTime"></param>
        public void FixedUpdate(float fixedDeltaTime)
        {
            CurrentState?.OnFixedUpdateState(fixedDeltaTime);
        }
    }
}


